/* * RHQ Management Platform * Copyright (C) 2005-2013 Red Hat, Inc. * All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation version 2 of the License. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software Foundation, Inc., * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA */ package org.rhq.enterprise.gui.common.framework; import java.io.IOException; import java.util.Map; import javax.el.ELException; import javax.el.ValueExpression; import javax.faces.FacesException; import javax.faces.application.ViewHandler; import javax.faces.component.UIViewRoot; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import com.sun.facelets.FaceletViewHandler; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.rhq.core.gui.util.FacesContextUtility; import org.rhq.core.gui.util.FacesExpressionUtility; import org.rhq.enterprise.server.util.HibernatePerformanceMonitor; /** * @author Joseph Marques */ public class FaceletRedirectionViewHandler extends FaceletViewHandler { private static final Log LOG = LogFactory.getLog(FaceletRedirectionViewHandler.class); public FaceletRedirectionViewHandler(ViewHandler handler) { super(handler); } @Override public String getActionURL(FacesContext facesContext, String viewId) { // Evaluate any EL variables that are contained in the view id. // (e.g. "/rhq/resource/artifact/view.xhtml?id=#{param.id}") ValueExpression valueExpression = FacesExpressionUtility.createValueExpression(viewId, String.class); String actionURL = FacesExpressionUtility.getValue(valueExpression, String.class); return actionURL; } @Override public void renderView(FacesContext context, UIViewRoot viewToRender) throws IOException, FacesException { long monitorId = HibernatePerformanceMonitor.get().start(); super.renderView(context, viewToRender); HibernatePerformanceMonitor.get().stop(monitorId, "URL:" + getURL(viewToRender)); } private String getURL(UIViewRoot viewToRender) { StringBuilder results = new StringBuilder(viewToRender.getViewId()); boolean first = true; for (Map.Entry<String, Object> urlParam : viewToRender.getAttributes().entrySet()) { if (first) { results.append('?'); first = false; } else { results.append('&'); } results.append(urlParam.getKey()).append("=").append(urlParam.getValue()); } return results.toString(); } @Override protected void handleRenderException(FacesContext context, Exception ex) throws IOException, ELException, FacesException { try { if (context.getViewRoot().getViewId().equals("/portal/rhq/common/error.xhtml")) { /* * This is to protect from infinite redirects if the error page itself * has an error; in this case, revert to the default error handling, * which should provide extra context information to debug the issue */ LOG.error("Redirected back to ourselves, there must be a problem with the error.xhtml page", ex); super.handleRenderException(context, ex); // normal, ugly error page used to diagnose the issue return; // return early, to prevent infinite redirects back to ourselves } // let's put this in the server log along with showing the user LOG.error("Error processing user request", ex); // squirrel the exception away in the session so it's maintained across the redirect boundary FacesContext facesContext = FacesContext.getCurrentInstance(); ExternalContext externalContext = facesContext.getExternalContext(); Map<String, Object> sessionMap = externalContext.getSessionMap(); sessionMap.put("GLOBAL_RENDER_ERROR", ex); FacesContextUtility.getResponse().sendRedirect("/portal/rhq/common/error.xhtml"); } catch (IOException ioe) { LOG.fatal("Could not process redirect to handle application error", ioe); } } }